#ifndef HANDLEHMAP_HPP
#define HANDLEHMAP_HPP

#include <stdio.h>
#include <cassert>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include "json11/json11.hpp"
#include <list>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <type_traits>
#include <fstream>
#include "sys/io.h"
#include <unistd.h>

using namespace std;
using namespace json11;


int judgeNameInMapJson(string name,Json::array map_array){
    for(int k=0;k<map_array.size();k++){
        if(name==map_array[k]["mapFileName"].string_value()){
            return 1;//exist
        }
    }
    return 0;//not exist	
}

void writeMapJson(Json::array m_total,string file_path){
	string sspace = "		";
	string ssspace = "			";
	ofstream inputJson(file_path.c_str(), ios::trunc);
	if(!inputJson.is_open()){
		cout << "failed to open map.json" << endl;
		return ;
	}
	int m_num = m_total.size();
	//string s_temp;

	// д��json
	inputJson << "{" << endl;
	inputJson << "	" << "\"data\": [" << endl;

	for (int i = 0; i < m_num; i++) {

		inputJson << sspace << "{" << endl;
		inputJson << sspace << "\"Id\"" << ":  " << "\"" << m_total[i]["Id"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"mapFileName\"" << ":  " << "\"" << m_total[i]["mapFileName"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"createdAt\"" << ":  " << "\"" << m_total[i]["createdAt"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"tasks\"" << ":  " << "\"" << m_total[i]["tasks"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"pgmName\"" << ":  " << "\"" << m_total[i]["pgmName"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"pngName\"" << ":  " << "\"" << m_total[i]["pngName"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"yamlFileName\"" << ":  " << "\"" << m_total[i]["yamlFileName"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"mapInfo\"" << ":  " << "{" << endl;
		inputJson << ssspace << "\"resolution\"" << ":  " << m_total[i]["mapInfo"]["resolution"].number_value() << "," << endl;
		inputJson << ssspace << "\"gridHeight\"" << ":  " << m_total[i]["mapInfo"]["gridHeight"].int_value() << "," << endl;
		inputJson << ssspace << "\"gridWidth\"" << ":  " << m_total[i]["mapInfo"]["gridWidth"].int_value() << "," << endl;
		inputJson << ssspace << "\"originX\"" << ":  " << m_total[i]["mapInfo"]["originX"].number_value() << "," << endl;
		inputJson << ssspace << "\"originY\"" << ":  " << m_total[i]["mapInfo"]["originY"].number_value() << endl;
		inputJson << sspace << "}" << "," << endl;
		inputJson << sspace << "\"points\"" << ":  " << "\"" << m_total[i]["points"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"name\"" << ":  " << "\"" << m_total[i]["name"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"obstacleFileName\"" << ":  " << "\"" << m_total[i]["obstacleFileName"].string_value() << "\"" << endl;



		inputJson << sspace << "}";
		if (i < (m_num - 1)) {
			inputJson << "," << endl;
		}
	}

	inputJson << "	" << "]" << endl;
	inputJson << "}";

	inputJson.close();
}
int mapWrite(Json m1) {
	Json::array m_total;
	string file_path = "/root/TIC_MAP/map.json";
	if (access(file_path.c_str(), 0) != 0) {
		ofstream out_file(file_path.c_str());
		ROS_INFO("touch file ");
		if(!out_file.is_open()){
			cout << "out_file failed to open map.json" << endl;
			return -1;
		}
		out_file.close();
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "in_file failed to open map.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		m_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}

	m_total.push_back(m1);

	writeMapJson(m_total,file_path);
	cout<<"mapWrite successful!"<<endl;
	return 0;


}


int mapDelete(string mapkey) {
	string file_path = "/root/TIC_MAP/map.json";
	Json::array m_total;
	if (access(file_path.c_str(), 0) != 0) {
		
		cout << "file do not exist!!" << endl;
		return -1;
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open map.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		m_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();

	}

	ofstream inputJson(file_path.c_str(), ios::trunc);
	if(!inputJson.is_open()){
		cout << "failed to open map.json" << endl;
		return -1;
	}
	int m_num = m_total.size();
	//string s_temp;
	Json::object object_;
    Json::array map_info;
	for(int i = 0; i<m_num;i++){
		object_ = m_total[i].object_items();
		if (m_total[i]["mapFileName"].string_value() != mapkey){
			Json map_list_(object_);
			map_info.push_back(map_list_);
		}
	}
	writeMapJson(map_info,file_path);
	ROS_INFO("mapJsonDelete success");
	return 0;

}
int mapEdit(string mapkey,string newMapName) {
	string file_path = "/root/TIC_MAP/map.json";
	Json::array m_total;
	if (access(file_path.c_str(), 0) != 0) {
		
		cout << "file do not exist!!" << endl;
		return -1;
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open map.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		m_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();

	}
	int m_num = m_total.size();
	//string s_temp;
	Json::object object_;
    Json::array map_info;
	for(int i = 0; i<m_num;i++){
		object_ = m_total[i].object_items();
		if (m_total[i]["mapFileName"].string_value() == mapkey){	
			object_["mapFileName"] = newMapName;
		}
		Json map_list_(object_);
		map_info.push_back(map_list_);
	}
	writeMapJson(map_info,file_path);
	ROS_INFO("mapJsonEdit success");
	return 0;

}
#endif